package com.seeTools.boot.pc.service;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.seeTools.boot.pc.util.BeanUtils;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.Field;
import java.util.Collection;
import java.util.List;

/**
 * @Author: seeTools
 * @Date: 2023/10/14  13:20
 * @Version 1.0
 */
public class BaseServiceImpl<M extends BaseMapper<T>, T> extends ServiceImpl<M, T> implements BaseService<T> {


    /**
     * 根据字段获取数据
     *
     * @param field 字段名称
     * @param value 字段值
     * @return
     */
    @Override
    public List<T> findBy(String field, String value) {
        QueryWrapper<T> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(field, value);
        return list(queryWrapper);
    }


    /**
     * 根据字段获取数据
     *
     * @param key
     * @param value
     * @param <E>
     * @param <V>
     * @return
     */
    public <E, V> List<T> findBy(SFunction<E, V> key, Object value) {
        QueryWrapper<T> queryWrapper = new QueryWrapper<>();
        Field field = BeanUtils.getField(key);
        queryWrapper.eq(StrUtil.toUnderlineCase(field.getName()), value);
        return list(queryWrapper);
    }


    /**
     * 根據ids獲取數據
     *
     * @param ids
     * @return
     */
    @Override
    public List<T> findByIds(Long[] ids) {
        List<Long> allId = Convert.toList(Long.class, ids);
        return in("id", allId);
    }

    /**
     * 根据字段获取第一条数据
     *
     * @param field
     * @param value
     * @return
     */
    @Override
    public T findOne(String field, String value) {
        QueryWrapper<T> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(field, value);
        return getOne(queryWrapper, false);
    }

    /**
     * 根据字段获取数据第一条数据
     *
     * @param key
     * @param value
     * @param <E>
     * @param <V>
     * @return
     */
    public <E, V> T findOne(SFunction<E, V> key, Object value) {
        QueryWrapper<T> queryWrapper = new QueryWrapper<>();
        Field field = BeanUtils.getField(key);
        queryWrapper.eq(StrUtil.toUnderlineCase(field.getName()), value);
        return getOne(queryWrapper, false);
    }


    /**
     * 匹配符合条件的数据
     *
     * @param field
     * @param collection
     * @return
     */
    @Override
    public List<T> in(String field, Collection<?> collection) {
        QueryWrapper<T> queryWrapper = new QueryWrapper<>();
        queryWrapper.in(field, collection);
        return list(queryWrapper);
    }

    /**
     * 模糊查询符合条件的数据
     *
     * @param key
     * @param value
     * @param <E>
     * @param <V>
     * @return
     */
    @Override
    public <E, V> List<T> like(SFunction<E, V> key, Object value) {
        QueryWrapper<T> queryWrapper = new QueryWrapper<>();
        Field field = BeanUtils.getField(key);
        queryWrapper.like(StrUtil.toUnderlineCase(field.getName()), value);
        return list(queryWrapper);
    }

    /**
     * 在锁的情况下修改数据
     *
     * @param t
     * @return
     */
    @Override
    public boolean updateOnLock(T t) {
        QueryWrapper<T> queryWrapper = new QueryWrapper<>(t);
        List<T> list = list(queryWrapper);
        return updateById(t);
    }

    /**
     * 根据IDS删除数据
     *
     * @param ids
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean removeBatchByIds(Long[] ids) {
        List<Long> allId = Convert.toList(Long.class, ids);
        return removeBatchByIds(allId);
    }


    /**
     * 删除所有数据
     *
     * @return
     */
    @Override
    public boolean removeAll() {
        return remove(null);
    }


    /**
     * 获取所有数据
     *
     * @return
     */
    @Override
    public List<T> findAll() {
        return baseMapper.selectList(null);
    }
}
